<template>
  <div id="container">
    <div class="button">
      <dv-decoration-9 class="button-border1" :dur=3.5 style="width:70px;height:70px;">
        <!--    放大-->
        <el-button type="primary" class="zoomIn" circle icon="el-icon-my-add" @click="addUp" title="放大一级"></el-button>
      </dv-decoration-9>
      <dv-decoration-9 class="button-border2" :dur=3.5 style="width:70px;height:70px;">
        <!--    缩小-->
        <el-button type="primary" class="zoomOut" circle icon="el-icon-my-down" @click="reduce"
                   title="缩小一级"></el-button>
      </dv-decoration-9>
      <!--清除框选,全图-->
      <div class="middle" style="position: absolute; z-index: 10;right: 6.3%;">
        <a title="全屏" href="#" class="btn" @click="full"><i class="fa fa-arrows-alt" aria-hidden="true"></i></a>
        <a title="清除痕迹" href="#" class="btn" @click="clearLayers"><i class="fa fa-undo" aria-hidden="true"></i></a>
      </div>
      <div class="switch">
        <!--    热力图-->
        <el-switch class="heatMap" v-model="value" @change="HeatMap" active-text="打开热力图" inactive-text="关闭"
                   title="热力图"></el-switch>
        <!--    缓冲区 -->
        <el-switch class="buffer" v-model="buffer" @change="isBufferAnalyses" active-text="打开缓冲区" inactive-text="关闭"
                   title="缓冲区分析"></el-switch>
      </div>
    </div>
    <div id="map"></div>
    <MyBox></MyBox>
  </div>
</template>

<script>
import screenfull from "screenfull";
import MyBox from "@/components/MyBox";
import {shopFun, priceFun} from "@/js/featuresApi";
import {EventBus} from "@/main";

let map = null;
let MyHeat = null;
let heatMapLayer = null;
let drawLayer = null;
let pointLayerList = []
let center = [];
let editableLayers = null;
//测量距离时绘制的要素
let resultLayer = null;
//存放绘制线段的要素数组
let resultLayers = [];
//框选查询结果点
let resultMarker = null;
//用于多次框选时存放结果的数组
let resultMarkers = [];
let drawLayers = [];
//区分绘制图形种类的变量
let rectangle = null;
let polygon = null;
let shortLineList = [];
let shopList = null;
let bufferResultLayer = null;
let decoratorList = [];
let popupList = [];
export default {
  name: 'BaseMap',
  components: {MyBox},
  data() {
    return {
      center: [30.67, 104.07],
      value: false,
      buffer: false,
      zoom: 11,
      fullscreen: false,
      isHeat: false,
      isShowBuffer: false
    }
  },
  methods: {
    showMap() {
      let corner1 = L.latLng({lng: 50, lat: 50});    //设置左上角经纬度
      let corner2 = L.latLng({lng: 150, lat: 0});	//设置右下点经纬度
      let bounds = L.latLngBounds(corner1, corner2);  //构建视图限制范围
      let url = "http://localhost:8090/iserver/services/map-ChengduFresh/rest/maps/ChengduMap";
      map = L.map('map', {
        //去掉版权
        attributionControl: false,
        //投影坐标系
        // crs: L.supermap.CRS.TianDiTu_Mercator,
        crs: L.CRS.EPSG4326,
        //中心点
        center: this.center,
        //双击放大禁止
        doubleClickZoom: false,
        zoomControl: false,
        //最大，最小，当前缩放
        maxZoom: 18,
        minZoom: 4,
        zoom: this.zoom,
        maxBounds: bounds
      });
      //天地图
      const VEC_C = 'http://t6.tianditu.com/vec_c/wmts?layer=vec&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=';
      const CVA_C = 'http://t6.tianditu.com/cva_c/wmts?layer=cva&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk='
      L.tileLayer(VEC_C + '3018a42dca54502a4a0cd959217ef896', {
            maxZoom: 16,
            tileSize: 256,
            zoomOffset: 1,
          }
      ).addTo(map);
      L.tileLayer(CVA_C + '3018a42dca54502a4a0cd959217ef896', {
            maxZoom: 16,
            tileSize: 256,
            zoomOffset: 1,
          }
      ).addTo(map);
      /*new L.supermap
          .TiandituTileLayer({
            layerType: 'vec',
            key: '3018a42dca54502a4a0cd959217ef896'
          }).addTo(map);*/
      //地图叠加
      L.supermap.tiledMapLayer(url, {
        transparent: true,
        // clipRegionEnabled: true,
        //图层的透明度
        overlapDisplayed: true,
        opacity: 0.37
      }).addTo(map);
    },
    // 添加编辑功能
    addEdit() {
      editableLayers = new L.FeatureGroup();
      map.addLayer(editableLayers);
      let options = {
        position: 'bottomleft',
        draw: {
          polyline: false,
          polygon: {},
          circle: false,
          rectangle: false,
          circlemarker: false,
          marker: {},
        }
      };
      let drawControl = new L.Control.Draw(options)
      //添加绘图工具栏
      map.addControl(drawControl);
      handleMapEvent(drawControl._container, map);
      //对绘制的图形处理
      map.on(L.Draw.Event.CREATED, (e) => {
        for (let i = 0; i < drawLayers.length; i++) {
          map.removeLayer(drawLayers[i])
        }
        for (let i = 0; i < resultMarkers.length; i++) {
          for (let j = 0; j < drawLayers.length; j++) {
            editableLayers.removeLayer(drawLayers[j]);
            map.removeLayer(resultMarkers[i]);
          }
        }
        drawLayer = e.layer;
        //图框
        editableLayers.addLayer(drawLayer);
        drawLayers.push(drawLayer);
        //当绘制图形为多边形时，进行框选查询
        if (e.layerType === "polygon") {
          this.clearLayers1()
          let pointList = [];
          let range = drawLayer._latlngs[0];
          for (let i = 0; i < range.length; i++) {
            let point = [];
            point.push(range[i].lat, range[i].lng)
            pointList.push(point)
          }
          let polygon = L.polygon(pointList, {color: 'red'});
          this.selectQuery(polygon);
        }
        //当绘制线段时,进行距离查询
        if (e.layerType === 'polyline') {
          this.clearLayers1()
          let points = []
          let range = drawLayer._latlngs;
          for (let i = 0; i < range.length; i++) {
            let point = [];
            point.push(range[i].lat, range[i].lng)
            points.push(point)
          }
          // let marker1 = L.marker(points[0])
          // let marker2 = L.marker(points[1]);
          let markers = []
          for (let i = 0; i < points.length; i++) {
            markers.push(L.marker(points[i]))
          }
          let polyline = L.polyline(points);
          this.measureDistance(polyline, markers);
        }
        // 当画出的为点将触发这个函数， 进行网络分析
        if (e.layerType === "marker") {
          this.clearLayers1()
          shopFun((data) => {
            // 最后的坐标
            let pointList = []
            shopList = data.result.features.features
            for (let i = 0; i < shopList.length; i++) {
              let position = L.latLng(shopList[i].properties.LAT, shopList[i].properties.LNG)
              pointList.push(position)
            }
            this.getSortedPoint(e.layer._latlng.lng, e.layer._latlng.lat, pointList)
          })
        }
      });

      function handleMapEvent(div, map) {
        if (!div || !map) {
          return;
        }
        div.addEventListener('mouseover', function () {
          map.scrollWheelZoom.disable();
          map.doubleClickZoom.disable();
        });
        div.addEventListener('mouseout', function () {
          map.scrollWheelZoom.enable();
          map.doubleClickZoom.enable();
        });
      }
    },
    //框选查询
    selectQuery(e) {
      //查询内容及查询范围
      let param = new L.supermap.GetFeaturesByGeometryParameters({
        datasetNames: ["ChengduFresh:Shop"],
        geometry: e,
        fromIndex: 0,
        toIndex: 2222
      });
      let category = [];
      //调用接口搜索指定范围内数据
      priceFun(function (data) {
        let AllData = data.result.features.features;
        new L.supermap
            .FeatureService('http://localhost:8090/iserver/services/data-ChengduFresh/rest/data')
            .getFeaturesByGeometry(param, function (serviceResult) {
              resultMarker = L.geoJSON(serviceResult.result.features, {
                onEachFeature: function (feature, layer) {
                  for (let i = 0; i < AllData.length; i++) {
                    if (feature.properties.超市ID === AllData[i].properties.超市ID) {
                      var item = {};
                      item.pinlei = AllData[i].properties.品类
                      item.price = AllData[i].properties.价格元KG
                      category.push(item)
                    }
                  }
                  var popup = L.popup().setContent(function (data) {
                    var item = data.feature.properties;
                    var category = [];
                    var res = "";
                    for (let i = 0; i < AllData.length; i++) {
                      if (item.超市ID === AllData[i].properties.超市ID) {
                        var entity = {};
                        entity.pinlei = AllData[i].properties.品类;
                        entity.price = AllData[i].properties.价格元KG + "元/kg"
                        category.push(entity)
                      }
                    }
                    res += "店铺:" + item.NAME + "  " + "地址:" + item.ADNAME + "<br>";
                    for (let i = 0; i < category.length; i++) {
                      res += category[i].pinlei + "-------" + category[i].price + "<br>"
                    }
                    return res;
                  })
                  layer.bindPopup(
                      popup
                  );
                },
              })
              resultMarker.addTo(map)
              resultMarkers.push(resultMarker);
            });
      })
    },
    //距离查询
    measureDistance(polyline, markers) {
      // new L.supermap.TiledMapLayer("http://localhost:8090/iserver/services/map-ChengduFresh/rest/maps/ChengduMap").addTo(map);
      resultLayer = L.featureGroup().addTo(map);
      resultLayer.addLayer(polyline);
      resultLayer.addLayer(markers[0]);
      resultLayer.addLayer(markers[markers.length - 1]);

      resultLayers.push(resultLayer);
      let distanceMeasureParam = new L.supermap.MeasureParameters(polyline);
      new L.supermap
          .MeasureService("http://localhost:8090/iserver/services/map-ChengduFresh/rest/maps/ChengduMap")
          .measureDistance(distanceMeasureParam, function (serviceResult) {
            var content = "距离为：" + Math.round(serviceResult.result.distance) + '米';
            markers[markers.length - 1].bindPopup(content).openPopup(markers[markers.length - 1].getLatLng());
          });
    },
    // 是否展示缓冲区的方法
    isBufferAnalyses() {
      if (this.isShowBuffer === false) {
        this.bufferAnalyseProcess()
        this.isShowBuffer = true
      } else if (this.isShowBuffer === true) {
        map.removeLayer(bufferResultLayer)
        this.isShowBuffer = false
      }
    },
    // 缓冲区分析
    bufferAnalyseProcess() {
      let serviceUrl = 'http://localhost:8090/iserver/services/spatialAnalysis-ChengduFresh/restjsr/spatialanalyst'
      let dsBufferAnalystService = L.supermap.spatialAnalystService(serviceUrl);
      let dsBufferAnalystParameters = new SuperMap.DatasetBufferAnalystParameters({
        dataset: "Shop@ChengduFresh",
        bufferSetting: new SuperMap.BufferSetting({
          endType: SuperMap.BufferEndType.ROUND,
          leftDistance: {value: 3000},
          rightDistance: {value: 3000},
          semicircleLineSegment: 40
        }),
        isUnion: true
      });
      dsBufferAnalystService.bufferAnalysis(dsBufferAnalystParameters, function (serviceResult) {
        let result = serviceResult.result;
        bufferResultLayer = L.geoJSON(result.recordset.features).addTo(map);
      });
    },
    // 将商品变为小图标的方法
    becomeIcon() {
      shopFun((data) => {
        let myIcon = L.icon({
          iconUrl: 'shop1.svg',
          iconSize: [30, 20]
        })
        let shopList = data.result.features.features
        for (let i = 0; i < shopList.length; i++) {
          L.marker([shopList[i].properties.LAT, shopList[i].properties.LNG], {icon: myIcon}).addTo(map)
        }
      })
    },
    // 查找距离最短路径的方法
    getSortedPoint(x, y, shopPointList) {
      let serviceUrl = 'http://localhost:8090/iserver/services/transportationAnalyst-ChengduFresh/rest/networkanalyst/Network@ChengduFresh'
      let findPathService = L.supermap.networkAnalystService(serviceUrl);
      //设置网络分析结果参数
      let resultSetting = new SuperMap.TransportationAnalystResultSetting({
        returnEdgeFeatures: true,
        returnEdgeGeometry: true,
        returnEdgeIDs: true,
        returnNodeFeatures: true,
        returnNodeGeometry: true,
        returnNodeIDs: true,
        returnPathGuides: true,
        returnRoutes: true
      })
      //设置交通网络分析通用参数
      let analystParameter = new SuperMap.TransportationAnalystParameter({
        //分析结果返回内容
        resultSetting: resultSetting,
        //阻力字段的名称
        weightFieldName: "SmLength"
      });
      //设置最近设施分析参数
      let findClosetFacilitiesParams = new SuperMap.FindClosestFacilitiesParameters({
        //事件点，一般为需要获得服务设施服务的事件位置
        event: L.latLng(y, x),
        //要查找的设施点数量
        expectFacilityCount: 1,
        //设施点集合，一般为提供服务的服务设施位置
        facilities: shopPointList,
        //事件点和设施点是否通过节点ID号来指定
        isAnalyzeById: false,
        //交通网络分析通用参数
        parameter: analystParameter
      });
      //进行查找
      findPathService.findClosestFacilities(findClosetFacilitiesParams, (serviceResult) => {
        let result = serviceResult.result
        let roadList = []
        for (let i = 0; i < result.facilityPathList[0].route.geometry.coordinates[0].length; i++) {
          roadList.push([result.facilityPathList[0].route.geometry.coordinates[0][i][1], result.facilityPathList[0].route.geometry.coordinates[0][i][0]])
        }
        let realRouteLine = L.polyline(roadList, {
          weight: 12,
          color: '#FF9900'
        }).addTo(map)
        // 轨迹方向箭头
        let decorator = L.polylineDecorator(realRouteLine, {
          patterns: [{
            repeat: 60,
            symbol: L.Symbol.arrowHead({
              pixelSize: 5,
              headAngle: 75,
              polygon: false,
              pathOptions: {
                stroke: true,
                weight: 3,
                color: 'blue'
              }
            })
          }]
        }).addTo(map);
        let pathLength = 0;
        for (let i = 0; i < result.facilityPathList[0].pathGuideItems.features.length; i++) {
          pathLength += result.facilityPathList[0].pathGuideItems.features[i].properties.length
        }
        let viewList = []
        viewList.push(result.facilityPathList[0].facility.y)
        viewList.push(result.facilityPathList[0].facility.x)
        map.setView(viewList, 13)
        shopFun((data) => {
          for (let i = 0; i < data.result.features.features.length; i++) {
            if (parseFloat(data.result.features.features[i].properties.LAT) === parseFloat(viewList[0])) {
              let shopName = data.result.features.features[i].properties.NAME;
              let popup = L.popup()
                  .setLatLng(viewList)
                  .setContent(
                      `<h1>${shopName}</h1> <br>` +
                      '<h2>道路距离：</h2>' + `<h2>${pathLength.toFixed(2)}米</h2>`)
                  .openOn(map);
              popup.addTo(map);
              popupList.push(popup)
              break;
            }
          }
        })
        shortLineList.push(realRouteLine)
        decoratorList.push(decorator)
      })
    },
    //设置热力图是否显示
    HeatMap() {
      if (this.isHeat === false) {
        let tmpData = []
        shopFun(function (data) {
          tmpData = data.result.features.features
          heatMapLayer = new L.supermap.HeatMapLayer().addTo(map)
          heatMapLayer.setOpacity(0.4)
          heatMapLayer.addFeatures(tmpData);
        })
        this.isHeat = true
      } else if (this.isHeat === true) {
        map.removeLayer(heatMapLayer)
        this.isHeat = false
      }
    },
    //放大地图
    addUp() {
      map.zoomIn()
    },
    //缩小地图
    reduce() {
      map.zoomOut()
    },
    full() {
      if (!screenfull.isFullscreen) {
        screenfull.request();
      } else {
        screenfull.exit();
      }
    },
    //清除页面绘制的要素及结果
    clearLayers() {
      if (drawLayer) {
        for (let i = 0; i < resultMarkers.length; i++) {
          for (let j = 0; j < drawLayers.length; j++) {
            editableLayers.removeLayer(drawLayers[j]);
            map.removeLayer(resultMarkers[i]);
          }
        }
      } else {
        this.$message({
          showClose: true,
          message: '没有需清除的要素',
          center: true
        });
      }
      //清除绘制的要素
      for (let i = 0; i < resultLayers.length; i++) {
        map.removeLayer(resultLayers[i])
      }
      for (let i = 0; i < shortLineList.length; i++) {
        map.removeLayer(shortLineList[i])
      }
      for (let i = 0; i < decoratorList.length; i++) {
        map.removeLayer(decoratorList[i])
      }
      for (let i = 0; i < drawLayers.length; i++) {
        map.removeLayer(drawLayers[i])
      }
      for (let i = 0; i < popupList.length; i++) {
        map.removeLayer(popupList[i])
      }
      map.setView([30.67, 104.07], 11)
      let input = ''
      EventBus.$emit('close')
      EventBus.$emit('input', input)

    },
    clearLayers1() {
      //清除距离测量绘制的要素
      for (let i = 0; i < resultLayers.length; i++) {
        map.removeLayer(resultLayers[i])
      }
      for (let i = 0; i < shortLineList.length; i++) {
        map.removeLayer(shortLineList[i])
      }
      for (let i = 0; i < decoratorList.length; i++) {
        map.removeLayer(decoratorList[i])
      }
    }
  },
  mounted() {
    this.showMap()
    this.addEdit()
    this.becomeIcon()
    //接收经纬度
    EventBus.$on('center', (data) => {
      let popup = L.popup()
          .setLatLng(data)
          .setContent(
              '<h1>超市地点</h1> <br>' +
              '<h2>经纬度：</h2>' + `<h2>${data}</h2>`)
          .openOn(map);
      popup.addTo(map);
      map.setView(data, 12)
      //将popup弹窗放入数组
      popupList.push(popup)
    });
  }
}
</script>

<style>
#container {
  caret-color: transparent;
}

#map {
  height: 100%;
  width: 100%;
  z-index: 0;
  top: 0;
  position: absolute;
  left: 0;
  right: 0;
}

.button {
  width: 200px;
  height: 200px;
  position: absolute;
  left: 0;
  top: 0;
  z-index: 10;
}

/*button1边框*/
.button-border1 {
  position: absolute;
  z-index: 9;
  top: 45%;
  left: 4%;
}

/*放大*/
.zoomIn {
  position: absolute;
  z-index: 10;
}

/*缩小*/
.zoomOut {
  position: absolute;
  z-index: 10;
}

/*button2边框*/
.button-border2 {
  position: absolute;
  z-index: 9;
  top: 45%;
  left: 45%;
}

.switch {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: 10;
  top: 80%;
}

/*热力图*/
.heatMap {
  z-index: 10;
  top: 40%;
  left: 10%;
}

/*缓冲区*/
.buffer {
  z-index: 10;
  left: 10%;
  top: 10%;
}

/*放大按钮图标*/
.el-icon-my-add {
  background: url('../img/增加.png') no-repeat;
  font-size: 16px;
  background-size: cover;
}

.el-icon-my-add:before {
  content: "增";
  font-size: 16px;
  visibility: hidden;
}

.el-icon-my-down {
  background: url('../img/减少.png') no-repeat;
  font-size: 16px;
  background-size: cover;
}

.el-icon-my-down:before {
  content: "减";
  font-size: 16px;
  visibility: hidden;
}

/*——————————————————————————————————————————————————————————————————————————————————*/
.middle {
  white-space: nowrap;
  position: absolute;
  top: 5.3%;
  left: -11%;
  transform: translateY(-50%);
  height: 12%;
  text-align: center;
}

.btn {
  display: inline-block;
  width: 60px;
  height: 60px;
  background: #f1f1f1;
  margin: 10px;
  border-radius: 50%;
  box-shadow: 0 5px 15px -5px #00000070;
  color: #3498db;
  overflow: hidden;
  position: relative;
}

.btn i {
  line-height: 60px;
  font-size: 44px;
  transition: 0.2s linear;
}

.btn:hover i {
  transform: scale(1.3);
  color: #f1f1f1;
}

.btn::before {
  content: "";
  position: absolute;
  width: 120%;
  height: 120%;
  background: #3498db;
  transform: rotate(45deg);
  left: -110%;
  top: 90%;
}

.btn:hover::before {
  animation: anniu 0.7s 1;
  top: -10%;
  left: -10%;
}

@keyframes anniu {
  0% {
    left: -110%;
    top: 100%;
  }
  50% {
    left: -10%;
    top: -30%;
  }
  100% {
    left: -10%;
    top: -10%;
  }
}

</style>
